package com.xiaoze.question.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoze.common.utils.DateUtils;
import com.xiaoze.question.domain.QuestionAnswer;
import com.xiaoze.question.domain.QuestionItems;
import com.xiaoze.question.domain.QuestionScenario;
import com.xiaoze.question.dto.QuestionItemsOutput;
import com.xiaoze.question.mapper.QuestionItemsMapper;
import com.xiaoze.question.mapper.QuestionScenarioMapper;
import com.xiaoze.question.service.IQuestionItemsService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 试题题目管理Service业务层处理
 *
 * @author 胡昊泽
 * @date 2024-08-02
 */
@Service
public class QuestionItemsServiceImpl extends ServiceImpl<QuestionItemsMapper, QuestionItems> implements IQuestionItemsService {
    @Autowired
    private QuestionItemsMapper questionItemsMapper;

    @Autowired
    private QuestionScenarioMapper questionScenarioMapper;

    @Autowired
    private QuestionAnswerServiceImpl questionAnswerService;

    /**
     * 查询试题题目管理
     *
     * @param id 试题题目管理ID
     * @return 试题题目管理
     */
    @Override
    public QuestionItems selectQuestionItemsById(Long id) {
        // 根据id查询问题
        QuestionItems questionItems = questionItemsMapper.selectQuestionItemsById(id);
        // 根据试题id查询问题选项
        List<QuestionAnswer> questionAnswerList = questionAnswerService.list(new LambdaQueryWrapper<QuestionAnswer>().eq(QuestionAnswer::getQuestionId, String.valueOf(id)));
        if (CollectionUtils.isNotEmpty(questionAnswerList)) {
            questionItems.setQuestionAnswerList(questionAnswerList);
        }
        return questionItems;
    }

    /**
     * 查询试题题目管理列表
     *
     * @param questionItems 试题题目管理
     * @return 试题题目管理
     */
    @Override
    public List<QuestionItemsOutput> selectQuestionItemsList(QuestionItems questionItems) {
        // 1、查询出符合条件的数据
        List<QuestionItems> questionItemsList = questionItemsMapper.selectQuestionItemsList(questionItems);
        // 2、封装返回结果
        List<QuestionItemsOutput> questionItemsOutputList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(questionItemsList)) {
            // 取出列表中的策略id
            List<String> categoryIds = questionItemsList.stream().map(QuestionItems::getCategoryId).collect(Collectors.toList());
            // 根据策略id查询 对应的策略类型，然后进行匹配
            List<QuestionScenario> questionScenario = questionScenarioMapper.selectBatchIds(categoryIds);
            // 开始进行数据匹配
            questionItemsList.stream().map(m -> {
                QuestionItemsOutput questionItemsOutput = new QuestionItemsOutput();
                BeanUtils.copyProperties(m, questionItemsOutput);
                // 获取该条数据问卷id（业务场景id）
                String categoryId = m.getCategoryId();
                Optional<QuestionScenario> first = questionScenario.stream().filter(f -> f.getId() == Long.valueOf(categoryId)).findFirst();
                questionItemsOutput.setTitle(first.get().getTitle());
                questionItemsOutputList.add(questionItemsOutput);
                return m;
            }).collect(Collectors.toList());
        }
        return questionItemsOutputList;
    }

    /**
     * 新增试题题目管理
     *
     * @param questionItems 试题题目管理
     * @return 结果
     */
    @Override
    public int insertQuestionItems(QuestionItems questionItems) {
        questionItems.setCreateTime(DateUtils.getNowDate());
        questionItems.setUnCode(UUID.randomUUID().toString().replace("-", ""));
        // 根据要新增的场景编号，查询该问卷下面试题数量
        Integer count = questionItemsMapper.selectCount(new LambdaQueryWrapper<QuestionItems>().eq(QuestionItems::getCategoryId, questionItems.getCategoryId()));
        questionItems.setQuestionId(String.valueOf(count + 1));

        int count1 = questionItemsMapper.insertQuestionItems(questionItems);
        // 通过试题名称查询问题id
        QuestionItems questionItems1 = this.getBaseMapper().selectOne(new LambdaQueryWrapper<QuestionItems>().eq(QuestionItems::getQuestionName, questionItems.getQuestionName()));

        // 新增的该试题选项
        int sortNoCount = 1;
        List<QuestionAnswer> questionAnswerList = questionItems.getQuestionAnswerList();
        if (CollectionUtils.isNotEmpty(questionAnswerList)) {
            for (QuestionAnswer questionAnswer : questionAnswerList) {
                questionAnswer.setQuestionId(String.valueOf(questionItems1.getId()));
                questionAnswer.setSortNo((long) sortNoCount);
                questionAnswer.setUnCode(UUID.randomUUID().toString().replace("-", ""));
                questionAnswer.setCreateTime(DateUtils.getNowDate());
                questionAnswerService.save(questionAnswer);
                sortNoCount++;
            }
            sortNoCount = 1;
        }
        return count1;
    }

    /**
     * 修改试题题目管理
     *
     * @param questionItems 试题题目管理
     * @return 结果
     */
    @Override
    public int updateQuestionItems(QuestionItems questionItems) {

        questionItems.setUpdateTime(DateUtils.getNowDate());
        // 更新问题表信息
        this.updateById(questionItems);
        // 1、试题类型是单选或者多选的时候，会出现多种情况，需要分别考虑
        if (questionItems.getQuestionType().equals("2") || questionItems.getQuestionType().equals("3")) {
            // 1.1 此时会出现三种情况，新增、修改、删除
            // 1.1.1 新增 - 可以 通过是否上送题目选项编号来判断，没上送就是新增
            // 1.1.2 删除 - 上送的有选项id的，拿到上送的选项id和表里数量进行对比，上送的没有，表里有，代表是有删除的
            // 1.1.3 修改 - 上送的有选项id的，就是修改的数据

            // 1.2 获取上送的 问题选项list
            List<QuestionAnswer> questionAnswerList = questionItems.getQuestionAnswerList();
            if (CollectionUtils.isNotEmpty(questionAnswerList)) { // 不是空集合，则代表有上面三种情况
                // 1.2.1 抽取出 上送题目选项list中的题目选项id
                // 需要进行修改的信息
                List<QuestionAnswer> notNullList = questionAnswerList.stream().filter(f -> f.getId() != null).collect(Collectors.toList());
                // 需要进行新增的信息集合
                List<QuestionAnswer> nullList = questionAnswerList.stream().filter(f -> f.getId() == null).collect(Collectors.toList());
                List<Long> notNullIds = questionAnswerList.stream().filter(f -> f.getId() != null).map(QuestionAnswer::getId).collect(Collectors.toList());
                List<Long> nullIds = questionAnswerList.stream().filter(f -> f.getId() == null).map(QuestionAnswer::getId).collect(Collectors.toList());

                // 1.2.2处理 修改(新增需要排序id，所以先处理修改和删除)
                if (CollectionUtils.isNotEmpty(notNullList)) {
                    notNullList = notNullList.stream().map(f -> {
                        f.setUpdateTime(DateUtils.getNowDate());
                        return f;
                    }).collect(Collectors.toList());
                    questionAnswerService.updateBatchById(notNullList);
                }
                // 1.2.3 处理删除（需要求出 当前上送的id 和 数据库 中id比较，求出差集，然后删除差集中的id）
                // 1.2.3.1 根据题目id查询数据库 题目选项
                List<QuestionAnswer> questionAnswers = questionAnswerService.getBaseMapper().selectList(new LambdaQueryWrapper<QuestionAnswer>().eq(QuestionAnswer::getQuestionId, questionItems.getId()));
                // 1.2.3.2 求出差集
                List<Long> delIds = questionAnswers.stream().filter(f -> !notNullIds.contains(f.getId())).map(QuestionAnswer::getId).collect(Collectors.toList());
                //  1.2.3.3 删除
                if(CollectionUtils.isNotEmpty(delIds)){
                    questionAnswerService.removeByIds(delIds);
                }
                // 1.2.4 新增
                // 1.2.4.1 根据问题id查询出问题选项
                List<QuestionAnswer> questionAnswers1 = questionAnswerService.getBaseMapper().selectList(new LambdaQueryWrapper<QuestionAnswer>().eq(QuestionAnswer::getQuestionId, questionItems.getId()));
                Long count = 0L;
                if(CollectionUtils.isNotEmpty(questionAnswers1)){
                    List<Long> collect = questionAnswers1.stream().map(QuestionAnswer::getSortNo).collect(Collectors.toList());
                    count= collect.stream().max(Long::compare).orElse(0L);
                }
                // 开始进行新增处理 ,到此，新增的就结束了
                if (CollectionUtils.isNotEmpty(nullList)) {
                    Long finalCount = count;
                    List<QuestionAnswer> addList = nullList.stream().map(m -> {
                        m.setCreateTime(DateUtils.getNowDate());
                        m.setUnCode(UUID.randomUUID().toString().replace("-", ""));
                        m.setQuestionId(String.valueOf(questionItems.getId()));
                        m.setSortNo(finalCount + 1L);
                        return m;
                    }).collect(Collectors.toList());
                    questionAnswerService.saveBatch(addList);
                }
            } else { // 是空集合，代表用户要删除该题目下面的所有题目选项，直接根据问题id删除选项就可以了
                questionAnswerService.getBaseMapper().delete(new LambdaQueryWrapper<QuestionAnswer>().eq(QuestionAnswer::getQuestionId, questionItems.getId()));
            }
        } else { // 2、试题类型不是选择题的时候，直接删除该题目下面的题目选项
            questionAnswerService.getBaseMapper().delete(new LambdaQueryWrapper<QuestionAnswer>().eq(QuestionAnswer::getQuestionId, questionItems.getId()));
        }
        return 1;
    }

    /**
     * 批量删除试题题目管理
     *
     * @param ids 需要删除的试题题目管理ID
     * @return 结果
     */
    @Override
    public int deleteQuestionItemsByIds(Long[] ids) {
        return questionItemsMapper.deleteQuestionItemsByIds(ids);
    }

    /**
     * 删除试题题目管理信息
     *
     * @param id 试题题目管理ID
     * @return 结果
     */
    @Override
    public int deleteQuestionItemsById(Long id) {
        return questionItemsMapper.deleteQuestionItemsById(id);
    }
}
